package com.lfy.modules.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lfy.modules.blog.domain.RoleRouteContactEntity;
import com.lfy.modules.blog.domain.RouteEntity;
import com.lfy.modules.blog.domain.vo.role.RouteTreeVO;
import com.lfy.modules.blog.domain.vo.role.SaveRouteByRoleDTO;
import com.lfy.modules.blog.mapper.RouteEntityMapper;
import com.lfy.modules.blog.service.RoleRouteContactService;
import com.lfy.modules.blog.service.RouteService;
import com.lfy.modules.common.domain.R;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author 吕飞扬
* @description 针对表【route】的数据库操作Service实现
* @createDate 2024-04-03 01:14:11
*/
@Service
public class RouteServiceImpl extends ServiceImpl<RouteEntityMapper, RouteEntity>
    implements RouteService {
    @Resource
    private RoleRouteContactService roleRouteContactService;
    @Override
    public R<List<RouteTreeVO>> getRouteTree() {
        List<RouteEntity> routeEntities = this.list(null);
        if(CollectionUtils.isEmpty(routeEntities)){
            return R.success();
        }
        List<RouteTreeVO> vos = routeEntities.stream().map(item -> {
            RouteTreeVO routeTreeVO = new RouteTreeVO();
            BeanUtils.copyProperties(item, routeTreeVO);
            return routeTreeVO;
        }).collect(Collectors.toList());
        List<RouteTreeVO> parentNode = vos.stream().filter(item -> item.getParentId().equals(0L)).collect(Collectors.toList());
        for (RouteTreeVO routeTreeVO : parentNode) {
            routeTreeVO.setChildren(findChildren(routeTreeVO,vos));
        }
        return R.success(parentNode);
    }

    @Override
    public R<List<RouteTreeVO>> getRouteTreeListByRoleId(Long id) {
        R<Set<Long>> routeIdByRoleId = this.getRouteIdByRoleId(id);
        Set<Long> routeIds = routeIdByRoleId.getData();
        if(CollectionUtils.isEmpty(routeIds)){
            return R.success();
        }
        List<RouteEntity> routeEntities = this.list(new LambdaQueryWrapper<RouteEntity>().in(RouteEntity::getId, routeIds));
        if(CollectionUtils.isEmpty(routeEntities)){
            return R.success();
        }
        List<RouteTreeVO> routeTreeVOs = routeEntities.stream().map(item -> {
            RouteTreeVO routeTreeVO = new RouteTreeVO();
            BeanUtils.copyProperties(item, routeTreeVO);
            return routeTreeVO;
        }).collect(Collectors.toList());
        List<RouteTreeVO> treeVOs = routeTreeVOs.stream().filter(item -> item.getParentId().equals(0L)).collect(Collectors.toList());
        for (RouteTreeVO treeVO : treeVOs) {
            treeVO.setChildren(findChildren(treeVO,routeTreeVOs));
        }
        return R.success(treeVOs);
    }

    @Override
    public R<Void> addRouteByRoleId(SaveRouteByRoleDTO dto) {
        Long roleId = dto.getRoleId();
        List<Long> routeIds = dto.getRouteIds();
        List<RoleRouteContactEntity> routeContactEntities = routeIds.stream().map(item -> {
            RoleRouteContactEntity roleRouteContactEntity = new RoleRouteContactEntity();
            roleRouteContactEntity.setRoleId(roleId);
            roleRouteContactEntity.setRouteId(item);
            return roleRouteContactEntity;
        }).collect(Collectors.toList());
        this.roleRouteContactService.saveBatch(routeContactEntities);
        return R.success();
    }

    @Override
    public R<Void> removeRouteByRoleId(SaveRouteByRoleDTO dto) {
        Long roleId = dto.getRoleId();
        List<Long> routeIds = dto.getRouteIds();
        this.roleRouteContactService.remove(new LambdaQueryWrapper<RoleRouteContactEntity>().and(item-> item.eq(RoleRouteContactEntity::getRoleId,roleId).in(RoleRouteContactEntity::getRouteId,routeIds)));

        return R.success();
    }

    @Override
    public R<Set<Long>> getRouteIdByRoleId(Long id) {
        List<RoleRouteContactEntity> routeContactEntities = roleRouteContactService.list(new LambdaQueryWrapper<RoleRouteContactEntity>().eq(RoleRouteContactEntity::getRoleId, id));
        if(CollectionUtils.isEmpty(routeContactEntities)){
            return R.success();
        }
        Set<Long> ids = routeContactEntities.stream().map(RoleRouteContactEntity::getRouteId).collect(Collectors.toSet());
        return R.success(ids);

    }

    private List<RouteTreeVO> findChildren(RouteTreeVO routeTreeVO, List<RouteTreeVO> vos) {
        return vos.stream().filter(item->item.getParentId().equals(routeTreeVO.getId())).peek(item->item.setChildren(findChildren(item,vos))).collect(Collectors.toList());
    }

}




